package com.beerandjesus.webapp.sportofkings.handicapper.struts.action;

import com.beerandjesus.sportofkings.handicapper.app.CardAnalyzer;
import com.beerandjesus.sportofkings.handicapper.app.CardAnalyzerException;
import com.beerandjesus.sportofkings.handicapper.factory.ResultsTableFactory;
import com.beerandjesus.sportofkings.handicapper.model.RaceAnalysisResultVO;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.CardVOImpl;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.io.*;
import java.util.List;

/**
 * Date: Nov 4, 2012
 * Time: 10:27:17 AM
 */
public abstract class BaseAnalyzeAction extends ActionSupport {
    private String analysisResult;
    private String title;
    public static final String PARAM_RESULTS = "ANALYSIS_RESULTS";
    @Autowired
    private CardAnalyzer cardAnalyzer;
    @Autowired
    private ResultsTableFactory resultsTableFactory;
    private String trackCode;
    private String raceDate;
    @Value("${com.beerandjesus.sportofkings.handicapper.results.dir}")
    private String resultsDir;
    private static final Logger LOG = Logger.getLogger(BaseAnalyzeAction.class);

    public String getAnalysisResult() {
        return analysisResult;
    }

    public void setAnalysisResult(String analysisResult) {
        this.analysisResult = analysisResult;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    protected String constructPageTitle(String trackCode, String raceDate) {
        return trackCode + " " + raceDate;
    }

    protected String constructResultsFileName(String trackCode, String raceDate) {
        return PARAM_RESULTS + "_" + trackCode + "_" + raceDate;
    }

    protected String execute(String filePath) throws CardAnalyzerException {
        CardVOImpl vo = new CardVOImpl();
        vo.setFilePath(filePath);
        List<RaceAnalysisResultVO> results = getCardAnalyzer().analyzeCard(vo);
        String resultString = getResultsTableFactory().getOutputSimpleFormat(results);
        setAnalysisResult(resultString);
        RaceAnalysisResultVO firstResult = results.get(0);
        String trackCode = firstResult.getTrackCode();
        String raceDate = firstResult.getRaceDate();
        setTrackCode(trackCode);
        setRaceDate(raceDate);
        String resultsFileName = constructResultsFileName(trackCode, raceDate);
        try {
            writeFile(resultsFileName, resultString);
        } catch (IOException e) {
            throw new CardAnalyzerException(e.getMessage(), e);
        }
        return SUCCESS;
    }

    private void writeFile(String fileName, String resultString) throws IOException {
        File file = new File(resultsDir, fileName);
        LOG.info("Writing results file to " + file.getAbsolutePath());
        FileOutputStream fileOutputStream = null;
        OutputStreamWriter writer = null;
        try {
            fileOutputStream = new FileOutputStream(file);
            writer = new OutputStreamWriter(fileOutputStream);
            writer.write(resultString);
            writer.flush();
        } finally {
            try {
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                // Ignore
            }
        }
    }

    public CardAnalyzer getCardAnalyzer() {
        return cardAnalyzer;
    }

    public void setCardAnalyzer(CardAnalyzer cardAnalyzer) {
        this.cardAnalyzer = cardAnalyzer;
    }

    public ResultsTableFactory getResultsTableFactory() {
        return resultsTableFactory;
    }

    public void setResultsTableFactory(ResultsTableFactory resultsTableFactory) {
        this.resultsTableFactory = resultsTableFactory;
    }

    public String getRaceDate() {
        return raceDate;
    }

    public void setRaceDate(String raceDate) {
        this.raceDate = raceDate;
    }

    protected String readResult() throws IOException {
        String resultsFileName = constructResultsFileName(getTrackCode(), getRaceDate());
        File file = new File(getResultsDir(), resultsFileName);
        FileReader reader = new FileReader(file);
        LOG.info("Reading results file from " + file.getAbsolutePath());
        BufferedReader bufferedReader = new BufferedReader(reader);
        StringBuffer sb = new StringBuffer();
        try {
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line).append("\n");
            }
        } finally {
            try {
                reader.close();
                bufferedReader.close();
            } catch (IOException e) {
                // Ignore
            }
        }
        return sb.toString();
    }

    public String getTrackCode() {
        return trackCode;
    }

    public void setTrackCode(String trackCode) {
        this.trackCode = trackCode;
    }

    public void setResultsDir(String resultsDir) {
        this.resultsDir = resultsDir;
    }

    public String getResultsDir() {
        return resultsDir;
    }


}
